package javaer.starter.idea;

import com.google.common.collect.Sets;
import javaer.starter.constants.SymbolEnum;
import javaer.starter.idea.util.sql.FileRenderUtils;
import javaer.starter.model.*;
import javaer.starter.model.context.StarterContext;
import javaer.starter.placeholder.ParameterMapping;
import javaer.starter.placeholder.character.*;

import java.nio.file.Path;
import java.util.Set;

/**
 * @author yangzhen
 * @date 2023/7/13 14:57
 * @since 1.0.0
 */
public class Generator {

    private StarterContext starterContext;

    public Generator(StarterContext starterContext) {
        this.starterContext = starterContext;
    }

    public void generate() throws Exception {
        gen();
    }

    public void gen() throws Exception {

        ConfigVariableEscapeTokenHandler configVariableEscapeTokenHandler = new ConfigVariableEscapeTokenHandler(starterContext);
        MapperScanTokenHandler mapperScanTokenHandler = new MapperScanTokenHandler();
        MybatisVariableEscapeTokenHandler mybatisVariableEscapeTokenHandler = new MybatisVariableEscapeTokenHandler();
        ClassPackageTokenHandler classPackageTokenHandler = new ClassPackageTokenHandler();
        ImportMappingTokenHandler importMappingTokenHandler = new ImportMappingTokenHandler(starterContext.qualifiedNames, starterContext.basePackage);

        Path path = starterContext.artifactId_modulePath.get(starterContext.rootArtifactId);
        StarterTypeModel starterTypeModel = starterContext.getStarterTypeModel();
        Set<ModuleModel> moduleModels = starterContext.getModuleModels();
        Set<ModuleDependencyModel> moduleDependencyModels = starterContext.getModuleDependencyModels();
        Set<DependencyModel> dependencies = starterContext.getDependencies();
        Set<DependencyExcludedModel> excludedDependencies = starterContext.getExcludedDependencies();
        Set<TemplateModel> templateModels = starterContext.getTemplateModels();
        FileRenderUtils.generateSqlFile(path, StarterTypeModel.SQL_NAME, StarterTypeModel.SQL_TEMPLATE, Sets.newHashSet(starterTypeModel));
        FileRenderUtils.generateSqlFile(path, ModuleModel.SQL_NAME, ModuleModel.SQL_TEMPLATE, moduleModels);
        FileRenderUtils.generateSqlFile(path, ModuleDependencyModel.SQL_NAME, ModuleDependencyModel.SQL_TEMPLATE, moduleDependencyModels);
        FileRenderUtils.generateSqlFile(path, DependencyModel.SQL_NAME, DependencyModel.SQL_TEMPLATE, dependencies);
        FileRenderUtils.generateSqlFile(path, DependencyExcludedModel.SQL_NAME, DependencyExcludedModel.SQL_TEMPLATE, excludedDependencies);

        for (TemplateModel templateModel : templateModels) {
            if (!templateModel.getTemplateName().equals("pom.xml")) {
                String content = templateModel.getContent();
                content = configVariableEscapeTokenHandler.getParser().parse(content);
                if (templateModel.getTemplateName().endsWith(".xml")) {
                    content = mybatisVariableEscapeTokenHandler.getParser().parse(content);
                }
                content = mapperScanTokenHandler.getParser().parse(content);
                content = importMappingTokenHandler.getParser().parse(content);
                content = classPackageTokenHandler.getParser().parse(content);
                content = content.replace(starterContext.basePackage, SymbolEnum.BASE_PACKAGE.getSymbol());
                templateModel.setContent(content);
            }
        }
        configVariableEscapeTokenHandler.handleResult();
        FileRenderUtils.generateSqlFile(path, TemplateModel.SQL_NAME, TemplateModel.SQL_TEMPLATE, templateModels, starterContext.progressComponent);

        Set<ParameterMapping> parameterMappings = starterContext.parameterMappings;
        if (!parameterMappings.isEmpty()) {
            FileRenderUtils.generateConfigFile(path, "config", parameterMappings);
        }
    }
}
